home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / mawk.zip / PRINT.C < prev    next >
C/C++ Source or Header  |  1991-04-09  |  7KB  |  286 lines

  1.  
  2. /********************************************
  3. print.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the Awk programming language as defined in
  8. Aho, Kernighan and Weinberger, The AWK Programming Language,
  9. Addison-Wesley, 1988.
  10.  
  11. See the accompaning file, LIMITATIONS, for restrictions
  12. regarding modification and redistribution of this
  13. program in source or binary form.
  14. ********************************************/
  15.  
  16. /* $Log:    print.c,v $
  17.  * Revision 2.2  91/04/09  12:39:23  brennan
  18.  * added static to funct decls to satisfy STARDENT compiler
  19.  * 
  20.  * Revision 2.1  91/04/08  08:23:43  brennan
  21.  * VERSION 0.97
  22.  * 
  23. */
  24.  
  25. #include "mawk.h"
  26. #include "bi_vars.h"
  27. #include "bi_funct.h"
  28. #include "memory.h"
  29. #include "field.h"
  30. #include "scan.h"
  31. #include "files.h"
  32.  
  33. /*  static  functions */
  34. static void  PROTO( print_cell, (CELL *, FILE *) ) ;
  35. static void  PROTO( do_printf, (FILE *, char *, unsigned, CELL *) ) ;
  36. static void  PROTO( do_sprintf, (char *, unsigned, CELL *) ) ;
  37.  
  38.  
  39. static void print_cell(p, fp)
  40.   register CELL *p ;
  41.   register FILE *fp ;
  42. { register int len ;
  43.   
  44.   switch( p->type )
  45.   {
  46.     case C_NOINIT : break ;
  47.     case C_MBSTRN :
  48.     case C_STRING :
  49.     case C_STRNUM :
  50.         switch( len = string(p)->len )
  51.         {
  52.           case 0 :  break ;
  53.           case 1 :
  54.                     putc(string(p)->str[0],fp) ;
  55.                     break ;
  56.  
  57.           default :
  58.                     fwrite(string(p)->str, 1, len, fp) ;
  59.         }
  60.         break ;
  61.  
  62.     case C_DOUBLE :
  63.         fprintf(fp, string(field + OFMT)->str, p->dval) ;
  64.         break ;
  65.  
  66.     default :
  67.         bozo("bad cell passed to print_cell") ;
  68.   }
  69. }
  70.  
  71. /* on entry to bi_print or bi_printf the stack is:
  72.  
  73.    sp[0] = an integer k
  74.        if ( k < 0 )  output is to a file with name in sp[-1]
  75.        { so open file and sp -= 2 }
  76.  
  77.    sp[0] = k >= 0 is the number of print args
  78.    sp[-k]   holds the first argument 
  79. */
  80.  
  81. CELL *bi_print(sp)
  82.   CELL *sp ; /* stack ptr passed in */
  83. { register CELL *p ;
  84.   register int k ;
  85.   FILE *fp ;
  86.  
  87.   if ( (k = sp->type) < 0 )
  88.   { if ( (--sp)->type < C_STRING ) cast1_to_s(sp) ;
  89.     fp = (FILE *) file_find( string(sp), k ) ;
  90.     free_STRING(string(sp)) ;
  91.     k = (--sp)->type ;
  92.   }
  93.   else  fp = stdout ;
  94.  
  95.   if ( k )  
  96.   { p = sp - k ; /* clear k variables off the stack */
  97.     sp = p - 1 ;
  98.     while ( k-- > 1 ) 
  99.     { print_cell(p,fp) ; print_cell(bi_vars+OFS,fp) ;
  100.       cell_destroy(p) ; p++ ; }
  101.     
  102.     print_cell(p, fp) ;  cell_destroy(p) ;
  103.   }
  104.   else  
  105.   { sp-- ;
  106.     print_cell( &field[0], fp )  ; }
  107.  
  108.   print_cell( bi_vars + ORS , fp) ;
  109.   return sp ;
  110. }
  111.   
  112. /* the contents of format are preserved */
  113. static void do_printf( fp, format, argcnt, cp)
  114.   FILE *fp ;
  115.   char *format ; unsigned argcnt ;
  116.   CELL *cp ;  /* ptr to an array of arguments ( on the eval stack) */
  117. { register char *q ;
  118.   char  save ;
  119.   char *p = format ;
  120.  
  121.   while ( 1 )
  122.   { if ( ! (q = strchr(p, '%'))  )
  123.        if ( argcnt == 0 )
  124.        { fputs(p, fp) ; return ; }
  125.        else
  126.          rt_error("too many arguments in call to printf(%s)", 
  127.               format ) ; 
  128.  
  129.     if ( * ++q == '%' )
  130.     { fwrite( p, q-p, 1, fp) ; p = q+1 ; continue ; }
  131.  
  132.     if ( argcnt == 0 )
  133.         rt_error("too few arguments in call to printf(%s)", format) ; 
  134.  
  135.     if ( *q == '-' ) q++ ;
  136.     while ( scan_code[*(unsigned char*)q] == SC_DIGIT )  q++ ;
  137.     if ( *q == '.' )
  138.     { q++ ;
  139.       while ( scan_code[*(unsigned char*)q] == SC_DIGIT ) q++ ; }
  140.     
  141.     save = * ++q ;  *q = 0 ;
  142.     switch( q[-1] )
  143.     {
  144.       case 'c' :  
  145.       case 'd' :
  146.       case 'o' :
  147.       case 'x' :
  148.             if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
  149.             (void) fprintf(fp, p, (int) cp->dval) ;
  150.             break ;
  151.       case 'e' :
  152.       case 'g' :
  153.       case 'f' :
  154.             if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
  155.             (void) fprintf(fp, p, cp->dval) ;
  156.             break ;
  157.       case  's' :
  158.             if ( cp->type < C_STRING ) cast1_to_s(cp) ;
  159.             (void) fprintf(fp, p, string(cp)->str) ;
  160.             break ;
  161.       default :
  162.             rt_error("bad format string in call to printf(%s)",
  163.               format) ;
  164.     }
  165.     *q = save ; p = q ; argcnt-- ; cp++ ;
  166.   }
  167. }
  168.  
  169.  
  170. CELL *bi_printf(sp)
  171.   register CELL *sp ;
  172. { register int k ;
  173.   register CELL *p ;
  174.   FILE *fp ;
  175.  
  176.   if ( (k = sp->type) < 0 )
  177.   { if ( (--sp)->type < C_STRING ) cast1_to_s(sp) ;
  178.     fp = (FILE *) file_find( string(sp), k ) ;
  179.     free_STRING(string(sp)) ;
  180.     k = (--sp)->type ;
  181.   }
  182.   else  fp = stdout ;
  183.  
  184.   sp -= k-- ; /* sp points at the format string */
  185.   if ( sp->type < C_STRING )  cast1_to_s(sp) ;
  186.   do_printf(fp, string(sp)->str, k, sp+1) ;
  187.  
  188.   free_STRING(string(sp)) ;
  189.   for ( p = sp+1 ; k-- ; p++ )  cell_destroy(p) ;
  190.   return --sp ;
  191. }
  192.  
  193. CELL *bi_sprintf(sp)
  194.   CELL *sp ;
  195. { CELL *p ;
  196.   int argcnt = sp->type ;
  197.   void do_sprintf() ;
  198.  
  199.   sp -= argcnt-- ; /* sp points at the format string */
  200.   if ( sp->type < C_STRING )  cast1_to_s(sp) ;
  201.   do_sprintf(string(sp)->str, argcnt, sp+1) ;
  202.  
  203.   free_STRING(string(sp)) ;
  204.   for ( p = sp+1 ; argcnt-- ; p++ )  cell_destroy(p) ;
  205.  
  206.   sp->ptr = (PTR) new_STRING( temp_buff.string_buff ) ;
  207.   return sp ;
  208. }
  209.  
  210.  
  211. /* the contents of format are preserved */
  212. static void do_sprintf( format, argcnt, cp)
  213.   char *format ; 
  214.   unsigned argcnt ;
  215.   CELL *cp ;
  216. { register char *q ;
  217.   char  save ;
  218.   char *p = format ;
  219.   register char *target = temp_buff.string_buff ;
  220.  
  221.   *target = 0 ;
  222.   while ( 1 )
  223.   { if ( ! (q = strchr(p, '%'))  )
  224.        if ( argcnt == 0 )
  225.        { strcpy(target, p) ; 
  226.          /* check the result is not too large */
  227.          if ( main_buff[-1] != 0 )
  228.          { /* This may have damaged us -- try to croak out an error
  229.               message and exit */
  230.            rt_overflow("sprintf buffer", TEMP_BUFF_SZ) ;
  231.          }
  232.          return ; 
  233.        }
  234.        else
  235.          rt_error("too many arguments in call to sprintf(%s)", 
  236.              format ) ; 
  237.  
  238.     if ( * ++q == '%' )
  239.     { unsigned len ;
  240.  
  241.       (void) memcpy(target, p, len = q-p ) ;
  242.       p = q + 1 ; *(target += len) = 0 ;
  243.       continue ;
  244.     }
  245.  
  246.     if ( argcnt == 0 )
  247.       rt_error("too few arguments in call to sprintf(%s)", format) ; 
  248.  
  249.     if ( *q == '-' ) q++ ;
  250.     while ( scan_code[*(unsigned char*)q] == SC_DIGIT )  q++ ;
  251.     if ( *q == '.' )
  252.     { q++ ;
  253.       while ( scan_code[*(unsigned char*)q] == SC_DIGIT ) q++ ; }
  254.     
  255.     save = * ++q ;  *q = 0 ;
  256.     switch( q[-1] )
  257.     {
  258.       case 'c' :  
  259.       case 'd' :
  260.       case 'o' :
  261.       case 'x' :
  262.             if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
  263.             (void) sprintf(target, p, (int) cp->dval ) ;
  264.             target = strchr(target, 0) ;
  265.             break ;
  266.       case 'e' :
  267.       case 'g' :
  268.       case 'f' :
  269.             if ( cp->type != C_DOUBLE ) cast1_to_d(cp) ;
  270.             (void) sprintf(target, p, cp->dval ) ;
  271.             target = strchr(target, 0) ;
  272.             break ;
  273.       case  's' :
  274.             if ( cp->type < C_STRING ) cast1_to_s(cp) ;
  275.             (void) sprintf(target, p, string(cp)->str ) ;
  276.             target = strchr(target, 0) ;
  277.             break ;
  278.       default :
  279.             rt_error("bad format string in call to sprintf(%s)", 
  280.                 format) ;
  281.     }
  282.     *q = save ; p = q ; argcnt-- ; cp++ ;
  283.   }
  284. }
  285.  
  286.